package redis

import (
	"context"
	"time"

	"vov.cx/lib/env"

	"github.com/gomodule/redigo/redis"
)

const (
	keyRedisDSN  = "REDIS_DSN"
	keyRedisHost = "REDIS_HOST"
	keyRedisPort = "REDIS_PORT"
	keyRedisUsr  = "REDIS_USER"
	keyRedisPwd  = "REDIS_PASSWORD"
	keyRedisDB   = "REDIS_DB"
	keyEnabled   = "REDIS_ENABLED"
)

var redisPool *redis.Pool

func init() {
	if !env.IsTrue(keyEnabled) {
		return
	}

	redisPool = &redis.Pool{
		DialContext:     dial,
		TestOnBorrow:    testOnBorrow,
		MaxIdle:         3,
		MaxActive:       100,
		IdleTimeout:     time.Second * 10,
		Wait:            true,
		MaxConnLifetime: time.Second * 30,
	}
}

func dial(ctx context.Context) (redis.Conn, error) {
	dsn := getDSN()

	c, err := redis.DialContext(ctx, "tcp", dsn.Address())
	if err != nil {
		return nil, err
	}

	if dsn.HasAuth() {
		if _, err := c.Do("AUTH", dsn.AuthArgs()...); err != nil {
			_ = c.Close()
			return nil, err
		}
	} else {
		if _, err := c.Do("NOAUTH"); err != nil {
			_ = c.Close()
			return nil, err
		}
	}

	if _, err := c.Do("SELECT", dsn.DB); err != nil {
		_ = c.Close()
		return nil, err
	}

	return c, nil
}

func testOnBorrow(c redis.Conn, t time.Time) error {
	if time.Since(t) < time.Minute {
		return nil
	}
	_, err := c.Do("PING")
	return err
}
